package com.eclink.asset.service;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.eclink.asset.asset.domain.dao.FlowApply;
import com.eclink.asset.asset.service.AssetItemService;
import com.eclink.asset.asset.domain.dao.AssetItem;
import com.eclink.asset.asset.domain.dao.AssetInventoryRelItem;
import com.eclink.asset.domain.dto.*;
import com.eclink.asset.domain.query.AssetInventoryQuery;
import com.eclink.asset.enums.ApplyStateEnum;
import com.eclink.asset.enums.AssetInventoryItemResultEnum;
import com.eclink.asset.enums.AssetInventoryStateEnum;
import com.eclink.asset.mapper.AssetInventoryRelItemMapper;
import com.eclink.asset.pojo.query.ApplyQuery;
import com.eclink.asset.workflow.mapper.FlowApplyMapper;
import com.eclink.asset.workflow.service.ApplyService;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 资产分类表Service业务层处理
 *
 *
 * @author zcc
 */
@Service
public class AssetInventoryService {

    @Resource
    private ApplyService applyService;

    @Resource
    private FlowApplyMapper flowApplyMapper;

    @Resource
    private AssetInventoryRelItemMapper assetInventoryRelItemMapper;

    @Resource
    private AssetItemService assetItemService;

    private static final String APPLY_TYPE = "ZCPD";

    /**
     * 查询资产分类表列表
     *
     * @param query 查询条件
     * @param page 分页条件
     * @return 资产分类表
     */
    public List<FlowApply> selectList(AssetInventoryQuery query, Pageable page) {
        ApplyQuery applyQuery = new ApplyQuery();
        applyQuery.setApplyType(APPLY_TYPE);
        return applyService.selectList(applyQuery, page);
    }

    private void add(AssetInventorySaveDTO saveDTO) {

        FlowApply apply = new FlowApply();
        apply.setApplyType(APPLY_TYPE);
        apply.setApplyTypeName("资产盘点");
        apply.setState(ApplyStateEnum.TO_INVENTORY.getValue());
        Map<String,Object> rangeFormData = saveDTO.getRangeFormData();
        apply.setFormData(JSON.toJSONString(saveDTO.getBaseFormData()));
        apply.setFormDataRange(JSON.toJSONString(saveDTO.getRangeFormData()));


        List<AssetItem> list = assetItemService.selectListAll(rangeFormData);
        List<AssetInventoryRelItem> items = new ArrayList<>();

        for(AssetItem item : list) {
            AssetInventoryRelItem relItem = new AssetInventoryRelItem();
            BeanUtil.copyProperties(item, relItem);
            relItem.setState(AssetInventoryItemResultEnum.DRAFT.getValue());
            items.add(relItem);
        }

        apply.setNum(items.size());
        apply = applyService.addApply(apply);
        String id = apply.getId();
        for(AssetInventoryRelItem item : items) {
            item.setParentId(id);
            assetInventoryRelItemMapper.insert(item);
        }
    }

    /**
     * 保存
     * @param saveDTO dto
     */
    public void save(AssetInventorySaveDTO saveDTO) {
        add(saveDTO);
    }

    public Integer getNumAll(String id) {
        return assetInventoryRelItemMapper.selectCount(null);
    }

    public Integer getNumByState(String id, Integer state) {
        LambdaQueryWrapper<AssetInventoryRelItem> wrapper = new LambdaQueryWrapper<>();
        if (state != null) {
            wrapper.eq(AssetInventoryRelItem::getState, state);
        }

        wrapper.eq(AssetInventoryRelItem::getParentId, id);
        return assetInventoryRelItemMapper.selectCount(wrapper);
    }

    public Map<String, Integer> getNumMap(String id) {
        Map<String, Integer> map = new HashMap<>();
        for(AssetInventoryStateEnum e : AssetInventoryStateEnum.values() ) {
            map.put(e.getKey(), getNumByState(id, e.getValue()));
        }
        map.put("all", getNumByState(id, null));
        return map;
    }

    private Map<String, Integer> getResult(String id) {
        return getNumMap(id);
    }

    /**
     * 提交
     * @param id ID
     */
    @Transactional
    public void sub(String id) {
        LambdaUpdateWrapper<FlowApply> uw = new LambdaUpdateWrapper<>();
        uw.set(FlowApply::getResult, JSONObject.toJSONString(getResult(id)));
        uw.eq(FlowApply::getId, id);
        flowApplyMapper.update(null, uw);
        applyService.sub(id);
    }

    public FlowApply getById(String id) {
        return applyService.getById(id);
    }

    public List<AssetInventoryRelItem> getItemsById(String id) {
        QueryWrapper<AssetInventoryRelItem> qw = new QueryWrapper<>();
        qw.eq("parent_id", id);
        return assetInventoryRelItemMapper.selectList(qw);
    }

    /**
     * 删除
     * @param ids IDs
     *
     */
    public void deleteByIds(Long[] ids) {
        for(Long id : ids) {
            flowApplyMapper.deleteById(id);
            QueryWrapper<AssetInventoryRelItem> qw = new QueryWrapper<>();
            qw.eq("parent_id", id);
            assetInventoryRelItemMapper.delete(qw);
        }
    }

}
